﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Light.Utility
{
    public class DateHelper
    {

        public static DateTime Empty = DateTime.MinValue.AddMilliseconds(1.0);


        public static int Days(DateTime t1, DateTime t2)
        {
            TimeSpan span = new TimeSpan(t1.Ticks - t2.Ticks);
            return Convert.ToInt32(Math.Truncate(span.TotalDays));
        }

        public static DateTime GetEndOf(DateTime date, DateSpan span)
        {
            switch (span)
            {
                case DateSpan.Month:
                    return GetEndOfMonth(date);

                case DateSpan.Quarter:
                    return GetEndOfQuarter(date, GetQuarter(date));

                case DateSpan.Year:
                    return GetEndOfYear(date);
            }
            return GetEndOfDay(date);
        }

        public static DateTime GetEndOfCurrentDay()
        {
            return GetEndOfDay(DateTime.Now);
        }

        public static DateTime GetEndOfCurrentMonth()
        {
            return GetEndOfMonth(DateTime.Now.Month, DateTime.Now.Year);
        }

        public static DateTime GetEndOfCurrentWeek()
        {
            DateTime time = GetStartOfCurrentWeek().AddDays(6.0);
            return new DateTime(time.Year, time.Month, time.Day, 0x17, 0x3b, 0x3b, 0);
        }

        public static DateTime GetEndOfCurrentYear()
        {
            return GetEndOfYear(DateTime.Now.Year);
        }

        public static DateTime GetEndOfDay(DateTime date)
        {
            return new DateTime(date.Year, date.Month, date.Day, 0x17, 0x3b, 0x3b, 0);
        }

        public static DateTime GetEndOfLastMonth()
        {
            if (DateTime.Now.Month == 1)
            {
                return GetEndOfMonth(12, DateTime.Now.Year - 1);
            }
            return GetEndOfMonth(DateTime.Now.Month - 1, DateTime.Now.Year);
        }

        public static DateTime GetEndOfLastWeek()
        {
            DateTime time = GetStartOfLastWeek().AddDays(6.0);
            return new DateTime(time.Year, time.Month, time.Day, 0x17, 0x3b, 0x3b, 0);
        }

        public static DateTime GetEndOfLastYear()
        {
            return GetEndOfYear((int)(DateTime.Now.Year - 1));
        }

        public static DateTime GetEndOfMonth(DateTime date)
        {
            return GetEndOfMonth(date.Month, date.Year);
        }

        public static DateTime GetEndOfMonth(int Month, int Year)
        {
            return new DateTime(Year, Month, DateTime.DaysInMonth(Year, Month), 0x17, 0x3b, 0x3b, 0);
        }

        public static DateTime GetEndOfQuarter(DateTime date, Quarter Qtr)
        {
            return GetEndOfQuarter(date.Year, Qtr);
        }

        public static DateTime GetEndOfQuarter(int Year, Quarter Qtr)
        {
            if (Qtr == Quarter.First)
            {
                return new DateTime(Year, 3, DateTime.DaysInMonth(Year, 3), 0x17, 0x3b, 0x3b, 0);
            }
            if (Qtr == Quarter.Second)
            {
                return new DateTime(Year, 6, DateTime.DaysInMonth(Year, 6), 0x17, 0x3b, 0x3b, 0);
            }
            if (Qtr == Quarter.Third)
            {
                return new DateTime(Year, 9, DateTime.DaysInMonth(Year, 9), 0x17, 0x3b, 0x3b, 0);
            }
            return new DateTime(Year, 12, DateTime.DaysInMonth(Year, 12), 0x17, 0x3b, 0x3b, 0);
        }

        public static DateTime GetEndOfYear(DateTime date)
        {
            return GetEndOfYear(date.Year);
        }

        public static DateTime GetEndOfYear(int Year)
        {
            return new DateTime(Year, 12, DateTime.DaysInMonth(Year, 12), 0x17, 0x3b, 0x3b, 0);
        }

        public static Month GetMonth(DateTime date)
        {
            switch (date.Month)
            {
                case 1:
                    return Month.January;

                case 2:
                    return Month.February;

                case 3:
                    return Month.March;

                case 4:
                    return Month.April;

                case 5:
                    return Month.May;

                case 6:
                    return Month.June;

                case 7:
                    return Month.July;

                case 8:
                    return Month.August;

                case 9:
                    return Month.September;

                case 10:
                    return Month.October;

                case 11:
                    return Month.November;
            }
            return Month.December;
        }

        public static Quarter GetQuarter(DateTime date)
        {
            return GetQuarter(GetMonth(date));
        }

        public static Quarter GetQuarter(Month Month)
        {
            if (Month <= Month.March)
            {
                return Quarter.First;
            }
            if ((Month >= Month.April) && (Month <= Month.June))
            {
                return Quarter.Second;
            }
            if ((Month >= Month.July) && (Month <= Month.September))
            {
                return Quarter.Third;
            }
            return Quarter.Fourth;
        }

        public static DateTime GetStartOf(DateTime date, DateSpan span)
        {
            switch (span)
            {
                case DateSpan.Month:
                    return GetStartOfMonth(date);

                case DateSpan.Quarter:
                    return GetStartOfQuarter(date, GetQuarter(date));

                case DateSpan.Year:
                    return GetStartOfYear(date);
            }
            return GetStartOfDay(date);
        }

        public static DateTime GetStartOfCurrentDay()
        {
            return GetStartOfDay(DateTime.Now);
        }

        public static DateTime GetStartOfCurrentMonth()
        {
            return GetStartOfMonth(DateTime.Now.Month, DateTime.Now.Year);
        }

        public static DateTime GetStartOfCurrentWeek()
        {
            int dayOfWeek = (int)DateTime.Now.DayOfWeek;
            DateTime time = DateTime.Now.Subtract(TimeSpan.FromDays((double)dayOfWeek));
            return new DateTime(time.Year, time.Month, time.Day, 0, 0, 0, 0);
        }

        public static DateTime GetStartOfCurrentYear()
        {
            return GetStartOfYear(DateTime.Now.Year);
        }

        public static DateTime GetStartOfDay(DateTime date)
        {
            return new DateTime(date.Year, date.Month, date.Day, 0, 0, 0, 0);
        }

        public static DateTime GetStartOfLastMonth()
        {
            if (DateTime.Now.Month == 1)
            {
                return GetStartOfMonth(12, DateTime.Now.Year - 1);
            }
            return GetStartOfMonth(DateTime.Now.Month - 1, DateTime.Now.Year);
        }

        public static DateTime GetStartOfLastWeek()
        {
            int num = ((int)DateTime.Now.DayOfWeek) + 7;
            DateTime time = DateTime.Now.Subtract(TimeSpan.FromDays((double)num));
            return new DateTime(time.Year, time.Month, time.Day, 0, 0, 0, 0);
        }

        public static DateTime GetStartOfLastYear()
        {
            return GetStartOfYear((int)(DateTime.Now.Year - 1));
        }

        public static DateTime GetStartOfMonth(DateTime date)
        {
            return GetStartOfMonth(date.Month, date.Year);
        }

        public static DateTime GetStartOfMonth(int Month, int Year)
        {
            return new DateTime(Year, Month, 1, 0, 0, 0, 0);
        }

        public static DateTime GetStartOfQuarter(DateTime date, Quarter Qtr)
        {
            return GetStartOfQuarter(date.Year, Qtr);
        }

        public static DateTime GetStartOfQuarter(int Year, Quarter Qtr)
        {
            if (Qtr == Quarter.First)
            {
                return new DateTime(Year, 1, 1, 0, 0, 0, 0);
            }
            if (Qtr == Quarter.Second)
            {
                return new DateTime(Year, 4, 1, 0, 0, 0, 0);
            }
            if (Qtr == Quarter.Third)
            {
                return new DateTime(Year, 7, 1, 0, 0, 0, 0);
            }
            return new DateTime(Year, 10, 1, 0, 0, 0, 0);
        }

        public static DateTime GetStartOfYear(DateTime date)
        {
            return GetStartOfYear(date.Year);
        }

        public static DateTime GetStartOfYear(int Year)
        {
            return new DateTime(Year, 1, 1, 0, 0, 0, 0);
        }

        /// <summary>
        /// t1-t2
        /// </summary>
        /// <param name="t1"></param>
        /// <param name="t2"></param>
        /// <returns></returns>
        public static int Hours(DateTime t1, DateTime t2)
        {
            TimeSpan span = new TimeSpan(t1.Ticks - t2.Ticks);
            return Convert.ToInt32(Math.Truncate(span.TotalHours));
        }

        /// <summary>
        /// t1-t2
        /// </summary>
        /// <param name="t1"></param>
        /// <param name="t2"></param>
        /// <returns></returns>
        public static int Minutes(DateTime t1, DateTime t2)
        {
            TimeSpan span = new TimeSpan(t1.Ticks - t2.Ticks);
            return Convert.ToInt32(Math.Truncate(span.TotalMinutes));
        }

        /// <summary>
        /// t1-t2
        /// </summary>
        /// <param name="t1"></param>
        /// <param name="t2"></param>
        /// <returns></returns>
        public static int Months(DateTime t1, DateTime t2)
        {
            bool flag = t1 < t2;
            int num = 0;
            do
            {
                num++;
                t1 = t1.AddMonths(flag ? 1 : -1);
            }
            while ((flag & (t1 <= t2)) || (!flag & (t1 >= t2)));
            num--;
            return (flag ? -num : num);
        }

        /// <summary>
        /// t1-t2
        /// </summary>
        /// <param name="t1"></param>
        /// <param name="t2"></param>
        /// <returns></returns>
        public static int Seconds(DateTime t1, DateTime t2)
        {
            TimeSpan span = new TimeSpan(t1.Ticks - t2.Ticks);
            return Convert.ToInt32(Math.Truncate(span.TotalSeconds));
        }

        /// <summary>
        /// t1-t2
        /// </summary>
        /// <param name="t1"></param>
        /// <param name="t2"></param>
        /// <returns></returns>
        public static int Years(DateTime t1, DateTime t2)
        {
            bool flag = t1 < t2;
            int num = 0;
            do
            {
                num++;
                t1 = t1.AddYears(flag ? 1 : -1);
            }
            while ((flag & (t1 <= t2)) || (!flag & (t1 >= t2)));
            num--;
            return (flag ? -num : num);
        }

        /// <summary>
        /// 根据年、月、日生成一个日期值
        /// </summary>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <param name="day"></param>
        /// <returns></returns>
        public static DateTime GetDate(int year, int month, int day)
        {
            DateTime dt = GetEndOfMonth(month, year);
            int dayEnd = dt.Day;

            if (day < dayEnd)
            {
                dt = new DateTime(year, month, day);
            }
            return dt;
        }

    }




}
